# tornado是非阻塞式服务器的python web服务器框架
import tornado.httpserver
import tornado.ioloop
import tornado.options
from tornado.web import RequestHandler
from tornado.options import define, options
import json
import py_eureka_client.eureka_client as eureka_client
from eureka.indexKMeans import IndexKMeans
import eureka.common as com

# tornado.options.define 定义变量值；tornado.options.options 获取变量值
define("eurekaServer", default="http://192.168.1.133:8761/eureka/", help="eureka服务器地址", type=str)
define("appName", default="python", help="注册应用名称", type=str)
define("port", default=8001, help="程序端口号", type=int)

class User(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

def dictToUser(d):
    # jsonStr不能直接转自定义的class，需要通过dict再转一次
    return User(d["name"], d["age"])

class UserDto(object):
    def __init__(self, money):
        self.money = money

# restfulAPI功能实现在这里，本例可以通过FeignClient，传参用post，json方式
class DiseaseHandler(RequestHandler):
    def post(self):
        # 本例java feign调用时，传参都是通过post，json方式，参数获取是jsonByte，先转jsonStr，最后转jsonObj再获取参数
        jsonByte = self.request.body
        jsonStr = jsonByte.decode("utf-8")
        user = json.loads(jsonStr, object_hook = dictToUser)
        print("外部请求调用开始姓名:{},年龄:{}".format(user.name, user.age))
        commontResponse = com.CommonResponse(com.successCode, com.successMsg, UserDto(1000))
        self.write(commontResponse.__dict__)

class Hello(RequestHandler):
    def get(self):
        self.write("hello python eureka!")

def eurekaClient():
    tornado.options.parse_command_line()
    # 仅注册eureka服务，并每隔30秒发送心跳检测(需要发现其他组件用init)
    eureka_client.init_registry_client(eureka_server=options.eurekaServer,
                                       app_name=options.appName,
                                       instance_port=options.port)
    # 提供外部调用的接口
    # 路由系统其实就是 url 和 类 的对应关系，这里不同于其他框架，其他很多框架均是 url 对应 函数
    # Tornado中每个url对应的是一个类
    # 还支持二级域名的路由为正则表达式，例如 r"/story/([0-9]+)"
    app = tornado.web.Application(
        handlers=[
            (r"/postTest", DiseaseHandler),
            (r"/hello", Hello),
            (r"/kmeans", IndexKMeans)
        ]
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    # 并发数量
    # http_server.start(5)
    tornado.ioloop.IOLoop.instance().start()

# 本例实现了python注入到eureka服务，java通过feign调用，并获取入参和出参
if __name__ == "__main__":
    eurekaClient()